home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / lineed.zip / LINEED.C < prev    next >
C/C++ Source or Header  |  1992-04-05  |  52KB  |  2,143 lines

  1. /* LineEd (Line Editor) copyright (c) 1988/89/90/92 by M. Kimes
  2.    An XBBS Utility */
  3.  
  4. #include "lineed.h"
  5.  
  6. #ifdef __TURBOC__
  7.   #define _fastcall pascal
  8. #endif
  9.  
  10. #define ORIGMSG "Original msg "
  11. #define VERSION "1.06"
  12.  
  13. char * pascal stripcr(char *);
  14. void   pascal hitreturn(void);
  15. void   pascal cls (void);
  16. char   pascal inkey (void);
  17. char   pascal carrchk (void);
  18. char   pascal fossil (char function, char arg);
  19. char   pascal printm (char *text);
  20. void   cdecl  deinitialize (void);
  21. char * pascal genin (char length,char password,char caps,char hot,char type);
  22. long   pascal getxbbstime(void);
  23. char   pascal specialkey(char);
  24. char   pascal specialmod(void);
  25. char * pascal rstrip(char *);
  26. char * pascal lstrip(char *);
  27. int    cdecl  break_handler(void);
  28. void   pascal chat(void);
  29. void   pascal rawdir (char *,char);
  30. int    pascal checkafile(char *);
  31. char   pascal readtext (char *);
  32. int    cdecl  printfm(char *,...);
  33. int    pascal do_args (int argc, char *argv[]);
  34. word   pascal enter (word);
  35. void   pascal patchup           (word,int);
  36. void   pascal delete            (void);
  37. struct line * pascal dls_store (struct line *);
  38. struct line * pascal find      (word);
  39. void   pascal search            (void);
  40. word   pascal list               (void);
  41. word   pascal save              (word,word);
  42. void   pascal load              (char);
  43. int    pascal menu_select        (void);
  44. void   pascal wrap              (char *,char *);
  45. word   pascal findlast           (void);
  46. void   pascal printheader       (void);
  47. struct line * pascal newbuffer (void);
  48. void   pascal deleteline        (word);
  49. void   pascal quoter               (void);
  50. void   pascal edit              (word);
  51. void   pascal view              (char);
  52. void   pascal movelines         (void);
  53. void   pascal status            (char);
  54. void   pascal quit             (char);
  55. void   pascal formpara          (void);
  56. int    pascal printg(char *text);
  57.  
  58. /***********************************/
  59. /* functions in ansi.c (low-level) */
  60. /***********************************/
  61.  
  62. /* NOTE:  all screen output except for status line should go (ultimately)
  63.  * through ansi().
  64.  */
  65. int _fastcall  ansi (char *buf);
  66. int            aprintf(char *str,...);
  67. void _fastcall set_screensize (int reservedbotlines,int reservedtoplines);
  68. void _fastcall put_char (char c,char attr,int x,int y);
  69. void _fastcall pos_hardcursor (int x,int y);
  70. void _fastcall hardcursor_off (void);
  71. void _fastcall hardcursor_on (int x,int y);
  72. void _fastcall scroll_up (int tx,int ty,int bx,int by,char attr);
  73. void _fastcall clearwindow (int tx,int ty,int bx,int by,char attr);
  74. void _fastcall cleartoeol (int x,int y,int ex,char attr);
  75. void _fastcall validate_cursor(void);
  76. int _fastcall dputs (int x,int y,char attr,char *s);
  77. int dprintf (int x,int y,char attr,char *str,...);
  78. void _fastcall get_hardcursorpos (int *x,int *y);
  79.  
  80. extern int    fakemaxx,fakemaxy;
  81. extern char   curattr;
  82. extern int    maxx,maxy;
  83. #ifndef OS2
  84.  extern int    usebios;
  85. #endif
  86. extern int    useansi;
  87. extern int    tabspaces;
  88.  
  89. extern void _fastcall (*pause_mtask)(void);
  90. extern void pascal set_mtask (void);
  91.  
  92. char   quoting = 0;
  93. char   chatting = 0;
  94. long   timelimit = 1800L;
  95. word   baud = 0;
  96. char   pauser = 0;
  97. char   graphics = 0;
  98. char   numlines = 24;
  99. word   lines = 0;
  100. long   startt = 0;
  101. char   commport = 0;
  102. char   chatted = 0;
  103. char   fname[133] = "";
  104. char   mode = 1;
  105. char   username[37] = "";
  106. struct ffblk filestat;
  107. char   uwidth = 80;
  108. char   noslice = 0;
  109.  
  110. struct line {
  111.   char text[81];
  112.   char terminator[3];
  113.   word num;
  114.   struct line *next;
  115.   struct line *prior;
  116. };
  117.  
  118. struct line * start;
  119. struct line * last;
  120. char temporary[257]="";
  121. union REGS rg;
  122. char ansii[8]={30,34,32,36,31,35,33,37};
  123. char from[36]="";
  124. char to[36]="";
  125. char date[20]="";
  126. char subj[72]="";
  127. char thisto[36]="";
  128. word maxlines=(word)65535;
  129.  
  130.  
  131. void cdecl main (argc,argv)
  132.  
  133.  int argc;
  134.  char *argv[];
  135.  
  136. {
  137.   char s[81];
  138.   char temp[127];
  139.   char choice;
  140.   word linenum=1;
  141.   word x;
  142.   FILE *fp;
  143.   struct line *info;
  144.   char *p;
  145.  
  146.  
  147.   set_screensize(1,0);
  148.   ctrlbrk(break_handler);
  149.  
  150.   strset(temporary,0);
  151.  
  152.   aprintf("\n\x1b[0;1;37mXBBS Line Text Editor (LineEd) copyright (c) 1988/89/90/92 by M. Kimes\n"
  153.           "Compiled: %s  %s\x1b[0m\n",__DATE__,__TIME__);
  154.  
  155.   start=NULL;
  156.   last=NULL;
  157.  
  158.   if(argc<2) {
  159.     aprintf("\nMust pass filename as first argument\nLineEd -H for help\n");
  160.     exit(3);
  161.   }
  162.   strcpy(fname,argv[1]);
  163.   strupr(fname);
  164.   do_args(argc,argv);
  165.   timelimit += time(NULL);
  166.   if(!noslice) set_mtask();
  167.   if ((uwidth<32) || (uwidth>80)) uwidth=80;
  168.  
  169.   fossil(INIT,0);
  170.   atexit(deinitialize);
  171.  
  172.   if ((fp=fopen("ONLINE.XBS","rb"))!=NULL) {
  173.     fgets(username,36,fp);
  174.     fclose(fp);
  175.   }
  176.   else {
  177.       if ((fp=fopen("USERINFO.XBS","r"))!=NULL) {
  178.         fgets(username,36,fp);
  179.         fclose(fp);
  180.         username[35]=0;
  181.         stripcr(username);
  182.       }
  183.   }
  184.   username[35]=0;
  185.   if (!*username) strcpy(username,"Unknown User");
  186.  
  187.   getxbbstime();
  188.  
  189.   cls();
  190.   status(1);
  191.   status(2);
  192.   printg("\x1b[0;1;37m");
  193.   printfm("XBBS Text Editor (LineEd) v%s\nWords will wrap at end of lines\n[Enter] on a blank line for options\n",VERSION);
  194.   printg("\x1b[0;1;32m");
  195.  
  196.   if (strnicmp(fname,"MSGTMP",6)) {
  197.         if (checkafile(fname)) {
  198.             printfm("\n%s is a new file.\n",fname);
  199.         }
  200.         else load(0);
  201.   }
  202.   else {
  203.         strcpy(temp,fname);
  204.         if(temp[strlen(temp)-1]!='.') strcat(temp,".");
  205.         strcat(temp,"HDR");
  206.         if ((fp=fopen(temp,"rt"))!=NULL) {
  207.             while(!feof(fp)) {
  208.                 fgets(temp,127,fp);
  209.                 temp[127]=0;
  210.                 stripcr(temp);
  211.                 p=strtok(temp," ");
  212.                 p=strtok(0,"\n");
  213.                 if(!p) continue;
  214.                 lstrip(p);
  215.                 rstrip(p);
  216.                 if(!stricmp(temp,"USER")) {
  217.                     strncpy(username,p,36);
  218.                     username[35]=0;
  219.                     status(1);
  220.                     status(2);
  221.                 }
  222.                 else if(!stricmp(temp,"RECP")) {
  223.                     strncpy(thisto,p,36);
  224.                     thisto[35]=0;
  225.                 }
  226.                 else if(!stricmp(temp,"FROM")) {
  227.                     strncpy(from,p,36);
  228.                     from[35]=0;
  229.                 }
  230.                 else if(!stricmp(temp,"TO")) {
  231.                     strncpy(to,p,36);
  232.                     to[35]=0;
  233.                 }
  234.                 else if(!stricmp(temp,"SUBJ")) {
  235.                     strncpy(subj,p,72);
  236.                     subj[71]=0;
  237.                 }
  238.                 else if(!stricmp(temp,"DATE")) {
  239.                     strncpy(date,p,20);
  240.                     date[19]=0;
  241.                 }
  242.             }
  243.             fclose(fp);
  244.             if(!*thisto) strcpy(thisto,from);
  245.         }
  246.         if (!checkafile(fname)) printm("\nQuotes in buffer\n");
  247.         else printm("\nNo Quotes available\n");
  248.   }
  249.  
  250.   enter (findlast()+1);
  251.   remove("0");      /* ???? */
  252.  
  253.   do {
  254.       choice=menu_select();
  255.       printm("\n");
  256.  
  257.    switch (choice) {
  258.     case  0:  break;
  259.     case 'E':
  260.     case 'T': linenum=findlast();
  261.               if (!linenum) break;
  262.               if (choice=='T') printm("\nReType");
  263.               else printm("\nEdit");
  264.               printfm(" which line # (1-%u): ",linenum);
  265.               strcpy(s,genin(5,0,0,0,NUM));
  266.               if (!*s) linenum=findlast();
  267.               else linenum=atoi(s);
  268.               if (!linenum) {
  269.                   printm("\nAborted");
  270.                   break;
  271.               }
  272.               if (find(linenum)==NULL) {
  273.                   printfm("\nCan't find line #%u\n",linenum);
  274.                   break;
  275.               }
  276.               info=find(linenum);
  277.               printg("\x1b[0;1;32m");
  278.               printfm("\nLine #%u now reads:\n%03u: %s",linenum,linenum,info->text);
  279.               if (choice=='E') {
  280.                     edit(linenum);
  281.                     break;
  282.               }
  283.               strcpy(temporary,info->text);
  284.               deleteline(linenum);
  285.               printm("\nReType line:");
  286.               enter(linenum);
  287.               break;
  288.     case 'C': info=find(findlast());
  289.               if (info && findlast()) {
  290.                 printg("\x1b[0;2;32m");
  291.                 printfm("\n%03u: %s",findlast(),info->text);
  292.               }
  293.               enter(findlast()+1);
  294.               break;
  295.     case 'I': linenum=findlast();
  296.               if (!linenum) break;
  297.               if(linenum>=maxlines) {
  298.                 if(linenum>=maxlines) {
  299.                     printg("\x1b[0;1;31m");
  300.                     printm("\nMaximum lines allowed already entered.\n");
  301.                     break;
  302.                 }
  303.               }
  304.               printfm("Begin insertion at line # (1-%u): ",linenum);
  305.               linenum=atoi(genin(5,0,0,0,NUM));
  306.               if (!linenum) {
  307.                  printm("\nAborted");
  308.                  break;
  309.               }
  310.               if (linenum!=1) if (find (linenum)==NULL) {
  311.                     printm("\nAborted");
  312.                     break;
  313.               }
  314.               if (find(linenum-1)!=NULL) {
  315.                     info=find(linenum-1);
  316.                     printg("\x1b[0;1;32m");
  317.                     printfm("\nPrevious line reads:\n%03u: %s",linenum-1,info->text);
  318.               }
  319.               enter(linenum);
  320.               break;
  321.     case 'D': delete();
  322.               break;
  323.     case 'R': list();
  324.               break;
  325.     case 'P':
  326.     case 'S': if (!findlast()) break;
  327.               if (mode) exit(save(1,findlast()));
  328.               printm("Enter filename: ");
  329.               strcpy(temp,fname);
  330.               if (*fname) {
  331.                 printfm("[%s] ",fname);
  332.               }
  333.               strcpy(s,genin(79,0,0,0,FLEPW));
  334.               if (*s) strcpy(fname,s);
  335.               if (!*fname) break;
  336.               strupr(fname);
  337.               status(1);
  338.               status(2);
  339.               if (choice=='P') {
  340.                   printm("\nWARNING: Same as current filename.\n");
  341.                   linenum=findlast();
  342.                   printg("\x1b[0;1;37m");
  343.                   printfm("Save line (1-%u) #",linenum);
  344.                   strcpy(s,genin(5,0,0,0,NUM));
  345.                   if (!*s) {
  346.                          printm("\nAborted\n");
  347.                          strcpy(fname,temp);
  348.                          status(1);
  349.                          status(2);
  350.                          break;
  351.                   }
  352.                   else {
  353.                     linenum=atoi(s);
  354.                     if ((linenum<1) || (linenum>findlast())) {
  355.                          printm("\nAborted");
  356.                          strcpy(fname,temp);
  357.                          status(1);
  358.                          status(2);
  359.                          break;
  360.                     }
  361.                     printm("-#");
  362.                     strcpy(s,genin(5,0,0,0,NUM));
  363.                     if (!*s) {
  364.                         x=linenum;
  365.                         printfm("%u",x);
  366.                     }
  367.                     else {
  368.                         x=atoi(s);
  369.                         if ((x<linenum) || (x>findlast())) {
  370.                             printm("\nAborted");
  371.                             strcpy(fname,temp);
  372.                             status(1);
  373.                             status(2);
  374.                             break;
  375.                         }
  376.                     }
  377.                   }
  378.                   save(linenum,x);
  379.                   strcpy(fname,temp);
  380.                   status(1);
  381.                   status(2);
  382.                   break;
  383.               }
  384.               save(1,findlast());
  385.               break;
  386.     case '>':
  387.               quoter();
  388.               break;
  389.     case 'L':
  390.     case 'A':
  391.               if (!findlast() && choice=='A') break;
  392.               if (!mode) {
  393.                   printm("Enter filename: ");
  394.                   strcpy(s,genin(79,0,0,0,FLEPW));
  395.                   if (!*s) break;
  396.                   strcpy(fname,s);
  397.                   strupr(fname);
  398.               }
  399.               if (choice=='L')load(0);
  400.               else load(1);
  401.               break;
  402.     case 'Q': quit(0);
  403.               break;
  404.     case 'N': if (!findlast()) break;
  405.               printm("Erase & start over...are you sure? (Y-n) ");
  406.               if (*genin(1,0,1,1,YESNO)=='N') break;
  407.               newbuffer();
  408.               start=NULL;
  409.               last=NULL;
  410.               enter(findlast()+1);
  411.               break;
  412.     case '$': if (mode) break;
  413.               rawdir("",1);
  414.               break;
  415.     case '!': printg("\x1b[0;1;37m");
  416.               printfm("\n%lu bytes free.\n",coreleft());
  417.               printfm("Filename: %s\n",fname);
  418.               printfm("%ld minutes remaining\n",(timelimit-getxbbstime())/60L);
  419.               printfm("%u lines remaining\n",maxlines-findlast());
  420.               if(*from) printfm("%sfrom %s\n",ORIGMSG,from);
  421.               if(*to) printfm("%sto %s\n",ORIGMSG,to);
  422.               if(*date) printfm("%sdate: %s\n",ORIGMSG,date);
  423.               if(*subj) {
  424.                 printfm("Subject:\n %s\n",subj);
  425.                 printm("New SUBJ:\n -> ");
  426.                 p=genin(72,0,0,0,SUBJECT);
  427.                 if(strlen(p)>2) strcpy(subj,p);
  428.                 printm("\n");
  429.               }
  430.               if(*thisto) {
  431.                 printfm("This msg to %s\n",thisto);
  432.                 printm("New TO: ");
  433.                 p=genin(36,0,0,0,NAME);
  434.                 if(*p) strcpy(thisto,p);
  435.                 printm("\n");
  436.               }
  437.               break;
  438.     case 'H':
  439.     case '?': view(1);
  440.               break;
  441.     case 'V': if (mode) break;
  442.               view(0);
  443.               break;
  444.     case 'M': movelines();
  445.               break;
  446.     case 'F': formpara();
  447.               break;
  448.       }
  449.   } while (1);
  450. }
  451.  
  452.  
  453. int cdecl break_handler (void) {
  454.  
  455.     return 1;
  456. }
  457.  
  458.  
  459. pascal menu_select() {
  460.  
  461.  char c=0;
  462.  
  463.   strset(temporary,0);
  464.   printg("\x1b[0;1;36m");
  465.   printfm("\n%ld minutes left.",(timelimit-getxbbstime())/60L);
  466.   printm("\n[C]ontinue [I]nsert [D]elete [R]ead ");
  467.   if (uwidth<79) printm("\n");
  468.   printm("Re[T]ype [N]ewbuff [S]ave [Q]uit [E]dit\n");
  469.   printm("[M]ove [F]orm [H]elp [!]Stats [>]Quote ");
  470.   if (!mode) {
  471.         if (uwidth<79) printm("\n");
  472.         printm("[L]oad [A]ppnd [P]rtSve [$]Dir [V]iew");
  473.   }
  474.  
  475.   printm("\n->  ");
  476.  
  477. NoGo:
  478.  
  479.   strset(temporary,0);
  480.   printm(BACKSPACE);
  481.   c=*genin(1,0,1,1,ALLL);
  482.   if (!strchr(">$!FMVPAETNCIDRSQL?H",c)) goto NoGo;
  483.   if (((c=='L') || (c=='$') || (c=='A') || (c=='P') || (c=='V')) && (mode)) goto NoGo;
  484.   return (c);
  485. }
  486.  
  487.  
  488. void pascal formpara (void)
  489. {
  490.  
  491.   char s[162];
  492.   char wrapped[162];
  493.   word linenum;
  494.   struct line *info,*p;
  495.  
  496.   if (findlast()<2) return;
  497.   printg("\x1b[0;1;35m");
  498.   printfm("\n(%u-%u) Reformat paragraph from which line #: ",1,findlast()-1);
  499.   strcpy(s,genin(5,0,0,0,NUM));
  500.   if (!*s) {
  501.      printm("\nAborted\n");
  502.      return;
  503.   }
  504.   else {
  505.         linenum=(word)atol(s);
  506.         if ((linenum<1) || (linenum>=findlast())) {
  507.             printm("\nAborted");
  508.             return;
  509.         }
  510.   }
  511.   info=find(linenum);
  512.   if (!info) return;
  513.   p=info->next;
  514.   if (!p) return;
  515.   while (*p->text!=' ' && *p->text) {
  516.         strcpy(s,info->text);
  517.         if (strstr(".?!:",&info->text[strlen(info->text)-1])) strcat(s,"  ");
  518.         else strcat(s," ");
  519.         strcat(s,p->text);
  520.         wrap(s,wrapped);
  521.         rstrip(s);
  522.         if (!*s) strcpy(s," ");
  523.         strcpy(info->text,s);
  524.         strcpy(info->terminator," \x8d");
  525.         if (*wrapped) strcpy(p->text,wrapped);
  526.         else {
  527.             deleteline(p->num);
  528.             p=info;
  529.         }
  530.         info=p;
  531.         p=info->next;
  532.         if (!p) break;
  533.   }
  534.   if (info) strcpy(info->terminator,"\r");
  535. }
  536.  
  537.  
  538. word pascal enter (word linenum) {
  539.  
  540.   struct line *info;
  541.   char wrapped[81];
  542.  
  543.   if(linenum<=maxlines) {
  544. /*    strset(temporary,0);  */
  545.       strset(wrapped,0);
  546.       printheader();
  547.   }
  548.  
  549.   do {
  550.     if(linenum>maxlines) {
  551.         printg("\x1b[0;1;31m");
  552.         printm("\nMaximum lines allowed already entered.\n");
  553.         return ((word)NULL);
  554.     }
  555.     info=(struct line *) malloc(sizeof(struct line));
  556.     if(!info) {
  557.         printm("\nOut of memory\n");
  558.         return ((word)NULL);
  559.     }
  560.     printg("\x1b[0;2;32m");
  561.     printfm("\n%03u: ",linenum);
  562.     printg("\x1b[0;1;32m");
  563.     if (*wrapped) strcpy(temporary,wrapped);
  564.     strset(wrapped,0);
  565.     strcpy(info->text,genin((uwidth-7),0,0,1,ALLL));
  566.     if (!*info->text) break;
  567.     info->num=linenum;
  568.     status(2);
  569.     if (strlen(info->text)<(uwidth-8) || strstr(".?!:",&info->text[strlen(info->text)-1])) strcpy(info->terminator,"\r");
  570.     else {
  571.         strcpy(info->terminator," \x8d");
  572.         if (info->text[(strlen(info->text)-1)]!=' ') {
  573.             wrap(info->text,wrapped);
  574.         }
  575.     }
  576.     rstrip(info->text);
  577.     if (find(linenum)) {
  578.         patchup(linenum,1);
  579.         printg("\x1b[0;1;31m");
  580.         printm("\n(Inserting)");
  581.     }
  582.     start=dls_store(info);
  583.     linenum++;
  584.  
  585.   } while (1);
  586.   return linenum;
  587. }
  588.  
  589.  
  590. void pascal wrap (temp,wrapped)
  591.  
  592. char *temp;
  593. char *wrapped;
  594.  
  595. {
  596.   word register x;
  597.  
  598.   strset(wrapped,0);
  599.  
  600.   rstrip(temp);
  601.   if (!*temp) strcpy(temp," ");
  602.  
  603.   if (strlen(temp)<(uwidth-8)) return;
  604.   if (!strchr(temp,' ')) return;
  605.   if (strlen(temp)>(uwidth-8)) {
  606.                         strcpy(wrapped,&temp[uwidth-7]);
  607.                         strrev(wrapped);
  608.                         temp[uwidth-7]=0;
  609.   }
  610.   for (x=(word)(uwidth-8);x>0;x--) {
  611.      if (temp[x]!=' ') {
  612.             printm(BACKSPACE);
  613.             strcat(wrapped,&temp[x]);
  614.             temp[x]=0;
  615.      }
  616.      else break;
  617.   }
  618.   rstrip(temp);
  619.   if (!*temp) strcpy(temp," ");
  620.   strrev(wrapped);
  621.  
  622. }
  623.  
  624.  
  625. void pascal patchup (n,incr)
  626.  
  627.  word n;
  628.  int incr;
  629.  
  630. {
  631.   struct line *i;
  632.  
  633.   i=find(n);
  634.   while(i) {
  635.     i->num=i->num+incr;
  636.     i=i->next;
  637.   }
  638. }
  639.  
  640.  
  641. struct line * pascal dls_store(i)
  642.  
  643.  struct line *i;
  644.  
  645. {
  646.   struct line *old,*p;
  647.  
  648.   if (last==NULL) {
  649.     i->next=NULL;
  650.     i->prior=NULL;
  651.     last=i;
  652.     return i;
  653.   }
  654.  
  655.   p=start;
  656.  
  657.   old=NULL;
  658.   while(p) {
  659.     if (p->num < i->num) {
  660.       old=p;
  661.       p=p->next;
  662.     }
  663.     else {
  664.      if(p->prior) {
  665.       p->prior->next=i;
  666.       i->next=p;
  667.       i->prior=p->prior;
  668.       p->prior=i;
  669.       return start;
  670.      }
  671.     i->next = p;
  672.     i->prior=NULL;
  673.     p->prior=i;
  674.     return i;
  675.   }
  676.  }
  677.  old->next=i;
  678.  i->next=NULL;
  679.  i->prior=old;
  680.  last=i;
  681.  return start;
  682. }
  683.  
  684.  
  685. char pascal readtext (s)
  686.  
  687.     char *s;
  688.  
  689. {
  690.     struct ffblk filestat;
  691.     char dostring[81];
  692.     signed char page;
  693.     char a;
  694.     ulong pos[102];
  695.     FILE *fp;
  696.     register word x;
  697.  
  698.   if (findfirst(s,&filestat,0)) {
  699. Failed:
  700.     printfm("\nCan't read %s\n",s);
  701.     return 0;
  702.   }
  703.   if (!filestat.ff_fsize) {
  704.         goto Failed;
  705.   }
  706.   if((fp=fopen(s,"r"))==NULL) {
  707.         goto Failed;
  708.   }
  709.   page=0;
  710.   pos[0]=0;
  711.   cls();
  712.   printg("\x1b[0;1;33m");
  713.   printfm(" -=-=Reading: %s=-=-  Page #%hu\n",s,page+1);
  714.   printg("\x1b[0;1;32m");
  715.   pauser=1;
  716.   lines=1;
  717.   while ((toupper(inkey())!='S') && (!feof(fp)) && (!ferror(fp))) {
  718. Domore:
  719.     if (fgets(dostring,81,fp)==NULL) break;
  720.     if (printm(dostring)) break;
  721.     if (strlen(dostring)>(uwidth-1)) lines++;
  722.     if (lines>=numlines-2) {
  723.         if (feof(fp)) break;
  724.         pauser=0;
  725.         printg("\x1b[0;1;33m");
  726.         printm(" [N]ext Page [P]revious Page [O]ver [M]ore [S]top: [N] ");
  727.         fossil(FLUSHOUT,0);
  728.         fossil(PURGEIN,0);
  729.         pos[page+1]=ftell(fp);
  730. Getitagain:
  731.         a=*genin(1,0,1,1,ALPHA);
  732.         switch (a) {
  733.             case 'S':   goto Abort;
  734.             case 'N':
  735.             case  0:    a=0;
  736.                         if (++page>100) page=1;
  737.                         pos[page]=ftell(fp);
  738.                         break;
  739.             case 'O':   fseek(fp,pos[page],SEEK_SET);
  740.                         break;
  741.             case 'P':
  742.             case '-':   if (page) {
  743.                             fseek(fp,pos[--page],SEEK_SET);
  744.                             break;
  745.                         }
  746.                         printm(BACKSPACE);
  747.                         goto Getitagain;
  748.             case 'M':   for (x=0;x<56;x++) printm(BACKSPACE);
  749.                         printg("\x1b[0;1;32m");
  750.                         pauser=1;
  751.                         lines=numlines-3;
  752.                         goto Domore;
  753.             default:    printm(BACKSPACE);
  754.                         goto Getitagain;
  755.         }
  756.         cls();
  757.         printg("\x1b[0;1;33m");
  758.         printfm("  -=-=Reading: %s=-=-  Page #%hu\n",s,page+1);
  759.         printg("\x1b[0;1;32m");
  760.         pauser=1;
  761.         lines=1;
  762.       }
  763.   }
  764. Abort:
  765.   pauser=0;
  766.   fclose(fp);
  767.   if (a=='S') return 1;
  768.   hitreturn();
  769.   status(1);
  770.   status(2);
  771.   ansi("\n");
  772.   return 0;
  773.  
  774. }
  775.  
  776.  
  777.  
  778. void pascal view (char type) {
  779.  
  780.   FILE *fp;
  781.   char s[81];
  782.   char filename[81];
  783.   char *p;
  784.  
  785.   if (type==1) {
  786.         p=searchpath("LineEd.HLP");
  787.         if(p) strcpy(filename,p);
  788.         else {
  789.             printm("\nSorry, no help available.\n");
  790.             return;
  791.         }
  792.   }
  793.   else {
  794.         printm("\nFilename to view? ");
  795.         strcpy(filename,genin(80,0,1,0,FLEPW));
  796.         printm("\n");
  797.   }
  798.   if (!*filename) return;
  799.  
  800.   printg("\x1b[0;1;33m");
  801.   if (checkafile(filename)) {
  802.       printfm("\nCan't find %s\n",filename);
  803.       return;
  804.   }
  805.   if (!filestat.ff_fsize) {
  806.       printm("\nNull-length file\n");
  807.       return;
  808.   }
  809.   if((fp=fopen(filename,"r"))==NULL) {
  810.     printfm("\nCannot open %s\n",filename);
  811.     fclose(fp);
  812.     return;
  813.   }
  814.   if (type==1) readtext(filename);
  815.   else {
  816.     printm("\n[T]yped || [P]aged? [P] ");
  817.     if (*genin(1,0,1,1,ALPHA)!='T') readtext(filename);
  818.     else {
  819.       printm("\n");
  820.       pauser = 1;
  821.       while ((inkey()!=' ') && (!feof(fp)) && (!ferror(fp))) {
  822.         if (fgets(s,80,fp)==NULL) break;
  823.         if (printm(s)) break;
  824.       }
  825.       fclose(fp);
  826.       ansi("\n");
  827.       pauser=0;
  828.     }
  829.   }
  830.   ansi("\n");
  831. }
  832.  
  833.  
  834. void pascal delete () {
  835.   char s[80];
  836.   word linenum;
  837.   word x;
  838.   word register y;
  839.  
  840.   linenum=findlast();
  841.   if (!linenum) return;
  842.   printg("\x1b[0;1;37m");
  843.   printfm("Delete line (1-%u) #",linenum);
  844.   strcpy(s,genin(5,0,0,0,NUM));
  845.   if (!*s) {
  846.     linenum=findlast();
  847.     x=linenum;
  848.     printfm("%u-#%u",linenum,x);
  849.   }
  850.   else {
  851.     linenum=(word)atol(s);
  852.     if ((linenum<1) || (linenum>findlast())) {
  853.          printm("\nAborted");
  854.          return;
  855.     }
  856.     printm("-#");
  857.     strcpy(s,genin(5,0,0,0,NUM));
  858.         if (!*s) {
  859.         x=linenum;
  860.         printfm("%u",x);
  861.     }
  862.     else {
  863.         x=atoi(s);
  864.         if ((x<linenum) || (x>findlast())) {
  865.           printm("\nAborted");
  866.           return;
  867.         }
  868.     }
  869.   }
  870.  
  871.  for(y=linenum;y<=x;y++) {
  872.   deleteline(linenum);
  873.  }
  874.  printm("\n");
  875. }
  876.  
  877.  
  878. void pascal deleteline (linenum)
  879.  
  880.   word linenum;
  881.  
  882. {
  883.  
  884.   struct line *info;
  885.  
  886.   info=find(linenum);
  887.   if(info) {
  888.     if(start==info) {
  889.       start=info->next;
  890.       if(start) start->prior=NULL;
  891.       else last=NULL;
  892.     }
  893.     else {
  894.       info->prior->next=info->next;
  895.       if(info!=last)
  896.     info->next->prior=info->prior;
  897.       else
  898.     last=info->prior;
  899.     }
  900.     farfree((struct line far*)info);
  901.     patchup(linenum+1,-1);
  902.   }
  903. }
  904.  
  905.  
  906. void pascal edit (word linenum) {
  907.  
  908.   char s[81],temp[81];
  909.   struct line *info;
  910.   char *p;
  911.   word register x;
  912.  
  913.   info=find(linenum);
  914.   if (!info) return;
  915.  
  916.   printm("\nString to alter? ");
  917.   strcpy(s,genin((uwidth-7),0,0,0,ALLL));
  918.   if (!*s) return;
  919.   p=strstr(info->text,s);
  920.   if (!p) {
  921.     printm("\nString not found.\n");
  922.     return;
  923.   }
  924.   printfm("\n%s\n",info->text);
  925.   for (x=0;x!=(p-info->text);++x) printm(" ");
  926.   for (x=0;x!=strlen(s);++x) printm("^");
  927.   printm("\nText to replace string? ");
  928.   strcpy(temp,genin((uwidth-7)-(strlen(info->text)-strlen(s)),0,0,0,ALLL));
  929.   if (!*temp) {
  930.             printm("\nDelete string from line? (y-N) ");
  931.             if (*genin(1,0,0,0,YESNO)!='Y') return;
  932.   }
  933.   x=strlen(s);
  934.   strcpy(s,&p[x]);
  935.   p[0]=0;
  936.   strcat(info->text,temp);
  937.   strcat(info->text,s);
  938.   printfm("\nLine #%03u now reads:\n%s",linenum,info->text);
  939.   return;
  940. }
  941.  
  942.  
  943. struct line * pascal find(linenum)
  944.  word linenum;
  945. {
  946.   struct line *info;
  947.  
  948.   info=start;
  949.   while (info) {
  950.     if (linenum==info->num) return info;
  951.     info=info->next;
  952.   }
  953.   return NULL;
  954. }
  955.  
  956. word pascal list()
  957. {
  958.   struct line *info;
  959.   word register lineno=0;
  960.   word register x;
  961.   char temp[127];
  962.   word lastline;
  963.   word prevline;
  964.  
  965.   lastline=findlast();
  966.  
  967.   info=start;
  968.  
  969.   if (lastline>(numlines)) {
  970.   printg("\x1b[0;1;37m");
  971.         printfm("\nRead from line # (1-%u): ",lastline);
  972.     strcpy(temp,genin(5,0,0,0,NUM));
  973.     if (!*temp) {
  974.         lineno=1;
  975.         printm("1");
  976.     }
  977.     else lineno=atoi(temp);
  978.     if ((lineno<1) || (lineno>lastline)) {
  979.         lineno=1;
  980.         for (x=0;x<strlen(temp);x++) printm(BACKSPACE);
  981.         printm("1");
  982.     }
  983.     printm("\n[Space] to halt\n");
  984.     info=find(lineno);
  985.     lineno--;
  986.   }
  987.  
  988.   prevline=lineno;
  989.   while(info) {
  990.     lineno++;
  991.     pauser=2;
  992.     printg("\x1b[0;2;32m");
  993.     printfm("%03u: ",info->num);
  994.     printg("\x1b[0;1;32m");
  995.     printm(info->text);
  996.     if (strlen(info->text)>(uwidth-6)) lines++;
  997.     pauser=1;
  998.     if (printm("\n")) break;
  999.     if (info->num==prevline) info->num=info->num+1;
  1000.     prevline=info->num;
  1001.     info=info->next;
  1002.     if (inkey()==' ') break;
  1003.   }
  1004.   pauser=0;
  1005.   return lineno;
  1006. }
  1007.  
  1008.  
  1009. word pascal findlast()
  1010. {
  1011.   struct line *info;
  1012.   word lineno=0;
  1013.  
  1014.   info=start;
  1015.  
  1016.   while(info) {
  1017.     lineno++;
  1018.     info->num=lineno;
  1019.     info=info->next;
  1020.   }
  1021.   return lineno;
  1022. }
  1023.  
  1024.  
  1025. word pascal save (word first,word tail) {
  1026.  
  1027.   struct line *info;
  1028.   char *p;
  1029.   FILE *fp;
  1030.  
  1031.   if (!*fname) return 0;
  1032.  
  1033.   if (!start) {
  1034.     printm("\nNo text to save.\n");
  1035.     return(1);
  1036.   }
  1037.  
  1038.   if ((fp=fopen(fname,"wb"))==NULL) {
  1039.     printfm("\nCannot open file %s\n",fname);
  1040.     return(1);
  1041.   }
  1042.   printm("\nSaving ");
  1043.   if (!mode) printm(fname);
  1044.   printm("...\n");
  1045.  
  1046.   info=find(first);
  1047.   while((info) && (info->num <= tail)) {
  1048.     p=info->text;
  1049.     while(*p) putc(*p++,fp);
  1050.     if (strnicmp(fname,"MSGTMP",6)) {
  1051.         putc('\r',fp);
  1052.         putc('\n',fp);
  1053.     }
  1054.     else fputs(info->terminator,fp);
  1055.     info=info->next;
  1056.   }
  1057.   fclose(fp);
  1058.   if(!strnicmp(fname,"MSGTMP",6)) {
  1059.  
  1060.     char temp[127];
  1061.  
  1062.     strcpy(temp,fname);
  1063.     if(temp[strlen(temp)-1]!='.') strcat(temp,".");
  1064.     strcat(temp,"HDR");
  1065.     remove(temp);
  1066.     fp=fopen(temp,"wb");
  1067.         if(!fp) return 0;
  1068.         if(*from) fprintf(fp,"NEWTO %s\r\n",from);
  1069.         if(*subj) fprintf(fp,"NEWSUBJ %s\r\n",subj);
  1070.     fclose(fp);
  1071.   }
  1072.   return(0);
  1073. }
  1074.  
  1075. struct line * pascal newbuffer() {
  1076.  
  1077.   struct line *temp;
  1078.  
  1079.     while(start) {
  1080.       temp=start;
  1081.       start=start->next;
  1082.       farfree((struct line far*)temp);
  1083.     }
  1084.     return (temp);
  1085.  
  1086. }
  1087.  
  1088.  
  1089. void pascal load (char type) {
  1090.  
  1091.   register unsigned int lnct;
  1092.   word size;
  1093.   struct line *info,*temp,*hold;
  1094.   char len;
  1095.   char *p;
  1096.   FILE *fp;
  1097.  
  1098.   if (!*fname) return;
  1099.  
  1100.   if (checkafile(fname)) {
  1101.       printfm("\nCan't find %s.\n",fname);
  1102.       return;
  1103.   }
  1104.   if (!filestat.ff_fsize) {
  1105.       printm("\nNull-length file.\n");
  1106.       return;
  1107.   }
  1108.  
  1109.   if((fp=fopen(fname,"rb"))==NULL) {
  1110.     printfm("\nCannot open %s.\n",fname);
  1111.     return;
  1112.   }
  1113.  
  1114.   printg("\x1b[0;1;35m");
  1115.  
  1116.   lnct=1;
  1117.   if ((!type) || (!findlast())) {
  1118.         newbuffer();
  1119.         temp=NULL;
  1120.         type=0;
  1121.   }
  1122.   else {
  1123.         temp=start;
  1124.         while(temp->next) temp=temp->next;
  1125.         lnct=findlast()+1;
  1126.   }
  1127.  
  1128.   if (!type) printm("\nLoading");
  1129.   else printm("\nAppending");
  1130.   if (!quoting) {
  1131.                             printfm(" %s...\n",fname);
  1132.   }
  1133.   else {
  1134.      printm(" Quotes...[Space] to halt\n");
  1135.   }
  1136.  
  1137.   hold=start;
  1138.   size=sizeof(struct line);
  1139.   start=(struct line *)malloc(size);
  1140.   if(!start) {
  1141.     printm("\nOut of memory\n");
  1142.     fclose(fp);
  1143.     return;
  1144.   }
  1145.   else if (type) {
  1146.      temp->next=start;
  1147.      start->prior=temp;
  1148.   }
  1149.  
  1150.   info=start;
  1151.   p=info->text;
  1152.   *p=0;
  1153.   len=0;
  1154.   if (quoting) pauser=1;
  1155.  
  1156. SkipNewLine:
  1157.  
  1158.   while (((*p=getc(fp))!=26) && (!feof(fp)) && (!ferror(fp))) {
  1159.     if (*p=='\n') continue;
  1160.     if (*p=='\r') goto BlankLine;
  1161.     p++;
  1162.     len++;
  1163.     while(((*p=getc(fp))!='\r') && (len<79) && (!feof(fp)) && (!ferror(fp))) {
  1164.          if (*p==26) {
  1165.             *p=0;
  1166.             break;
  1167.          }
  1168.          if ((*p==141) && (!strncmp(fname,"MSGTMP",6))) break;
  1169.          p++;
  1170.          len++;
  1171.     }
  1172.  
  1173. BlankLine:
  1174.  
  1175.     p[1]=0;
  1176.     len=0;
  1177.     if (*p==141) {
  1178.         if (((strlen(info->text)>1) && (p[-1]!=' ')) || (strlen(info->text)==1)) strcpy(info->terminator," \x8d");
  1179.         else strcpy(info->terminator,"\x8d");
  1180.                  }
  1181.     else strcpy(info->terminator,"\r");
  1182.     if ((*p=='\r') || (*p==141)) *p=0;
  1183.     else p[1]=0;
  1184.     if (quoting) {
  1185.           strcpy(info->terminator,"\r");
  1186.           if((strlen(info->text)+4)>(uwidth-1))lines++;
  1187.           if(printfm("%03u: %s\n",lnct,info->text))break;
  1188.     }
  1189.     if (*p) rstrip(info->text);
  1190.     info->num=lnct++;
  1191.     info->next=(struct line *) malloc(size);
  1192.     if(!info->next) {
  1193.       printm("\nOut of memory\n");
  1194.       fclose(fp);
  1195.       pauser=0;
  1196.       return;
  1197.     }
  1198.     info->prior=temp;
  1199.     temp=info;
  1200.     info=info->next;
  1201.     if (quoting) {
  1202.                     if (inkey()==' ') break;
  1203.     }
  1204.     p=info->text;
  1205.   }
  1206.   temp->next=NULL;
  1207.   last=temp;
  1208.   farfree((struct line far*)info);
  1209.   if (!type) start->prior=NULL;
  1210.   else start=hold;
  1211.   fclose(fp);
  1212.   pauser=0;
  1213. }
  1214.  
  1215.  
  1216. char pascal inkey (void) { /* MIMICS BASIC'S INKEY$ FUNCTION */
  1217.  
  1218.  char arg=0;
  1219.  
  1220.   rg.h.ah=11;
  1221.   int86(33,&rg,&rg);
  1222.   if (rg.h.al) {
  1223.     rg.h.ah=8;
  1224.     int86(33,&rg,&rg);
  1225.     if (rg.h.al)return((char)(rg.h.al));
  1226.     rg.h.ah=8;
  1227.     int86(33,&rg,&rg);
  1228.     arg=specialkey(rg.h.al);
  1229.     if (arg) return (arg);
  1230.    }
  1231.  
  1232.   if (baud) {
  1233.     arg=carrchk();
  1234.     if (!(arg & 1)) return (0);
  1235.     arg=(fossil(RECVWAIT,0));
  1236.     if (arg==27) return specialmod();
  1237.     else return (arg);
  1238.   }
  1239.  
  1240.   (*pause_mtask)();
  1241.   return (0);
  1242. }
  1243.  
  1244.  
  1245. char pascal specialkey (char a) {
  1246.  
  1247.  char tempause;
  1248.  char middle[82];
  1249.  int  drive;
  1250.  char dir[MAXDIR];
  1251.  
  1252.   tempause=pauser;
  1253.   pauser=0;
  1254.  
  1255.   switch (a) {
  1256.  
  1257.     case 35:                /* HANG UP */
  1258.        fossil(DTR,DOWN);
  1259.        exit(3);
  1260.        break;
  1261.  
  1262.     case 36:                /* SysOp SHELL */
  1263.       printm("\nThe SysOp has jumped to DOS...please wait...\n");
  1264.       status(0);
  1265.       fossil(FLUSHOUT,0);
  1266.       drive=getdisk();
  1267.       getcurdir(++drive,dir);
  1268.       fossil(DEINIT,0);
  1269.       puts("\nEXIT to return to editor");
  1270.       spawnlp (P_WAIT,"command.com",NULL);
  1271.       fossil(INIT,0);
  1272.       setdisk (--drive);
  1273.       strcpy(middle,"\\");
  1274.       strcat(middle,dir);
  1275.       chdir(middle);
  1276.       chatted=1;
  1277.       printm("\nThe SysOp has returned...please continue...\n");
  1278.       status(1);
  1279.       status(2);
  1280.       aprintf("\x1b[%d;1H\n",fakemaxy);
  1281.       break;
  1282.  
  1283.     case 72:                /* MORE TIME */
  1284.       timelimit+=60L;
  1285.       status(2);
  1286.       break;
  1287.  
  1288.     case 80:                /* LESS TIME */
  1289.       if (timelimit<=getxbbstime()) timelimit=0L;
  1290.        else timelimit-=60L;
  1291.        status(2);
  1292.        break;
  1293.  
  1294.     case 46:                /* CHAT ON/OFF */
  1295.       chatting=1-chatting;
  1296.       if (chatting) chat();
  1297.       return 13;
  1298.  
  1299.     case 81:                 /* FREE MEMORY */
  1300.      {
  1301.  
  1302.         word tempbaud;
  1303.  
  1304.       tempbaud=baud;
  1305.       baud=tempbaud;
  1306.       printfm("\n%c%lu bytes free.\n",4,coreleft());
  1307.       baud=tempbaud;
  1308.      }
  1309.  
  1310.     case 75:
  1311.       return 8;
  1312.  
  1313.     case 77:
  1314.       return 24;
  1315.  
  1316.     case 116:
  1317.       return 23;
  1318.  
  1319.     case 115:
  1320.       return 26;
  1321.  
  1322.     case 79:
  1323.       return 25;
  1324.  
  1325.     case 82:
  1326.       return 22;
  1327.  
  1328.     case 83:
  1329.       return 21;
  1330.  
  1331.     case 71:
  1332.       return 20;
  1333.  
  1334.     case 45:
  1335.       quit(1);
  1336.  
  1337.   }
  1338.  
  1339.   startt=getxbbstime();
  1340.   pauser=tempause;
  1341.  
  1342.   return 0;
  1343.  
  1344. }
  1345.  
  1346.  
  1347.  
  1348. void pascal cls (void)  /* MIMICS BASIC'S CLS FUNCTION LOCAL & REMOTE */
  1349.  
  1350. {
  1351.  
  1352.     char *p;
  1353.  
  1354.     lines = 0;
  1355.  
  1356.     if (graphics) {
  1357.         p = "\x1b[0m\x1b[2J";
  1358.         while(*p) {
  1359.             if(baud) while(!fossil(TRANSMIT,*p)) carrchk();
  1360.             p++;
  1361.         }
  1362.     }
  1363.     else if(baud) while(!fossil(TRANSMIT,'\x0c')) carrchk();
  1364.     ansi("\x1b[0m\x1b[2J");
  1365.     lines = 0;
  1366. }
  1367.  
  1368.  
  1369. char pascal fossil (function,arg)   /*  HANDLES MOST USEFUL FOSSIL CALLS */
  1370.  
  1371. char function;
  1372. char arg;
  1373.  
  1374. {
  1375.   if(!baud) return 0;
  1376.  
  1377.   if (function == FLUSHOUT)  {
  1378.      do {
  1379.        carrchk();
  1380.        rg.h.ah=3;
  1381.        rg.x.dx=commport;
  1382.        int86(20,&rg,&rg);
  1383.        if(!(rg.h.ah & 64)) (*pause_mtask)();
  1384.       }
  1385.      while (!(rg.h.ah & 64));
  1386.      return(0);
  1387.     }
  1388.  
  1389.   if (function == WATCHDOG) rg.h.al = arg;
  1390.   if (function == DTR) rg.h.al = arg;
  1391.   if (function == TRANSWAIT) rg.h.al = arg;
  1392.   if (function == TRANSMIT) rg.h.al = arg;
  1393.   if (function == ONOFF) rg.h.al = arg;
  1394.  
  1395.   rg.x.dx=commport;
  1396.   rg.h.ah=function;
  1397.   int86(20,&rg,&rg);
  1398.  
  1399.   if (function == INIT) {
  1400.      if (rg.x.ax != INITOK)  {
  1401.        aprintf("\nFossil not responding...RTFM.");
  1402.        exit (3);
  1403.      }
  1404.      return (0);
  1405.   }
  1406.  
  1407.   if (function == GETSTAT) {
  1408.       arg = rg.h.ah;
  1409.       if (rg.h.al & 128) {
  1410.         arg |= 128;
  1411.         return (arg);
  1412.       }
  1413.       arg &= 127;
  1414.       return (arg);
  1415.   }
  1416.  
  1417.   if (function == RECVWAIT) return (rg.h.al);
  1418.   if (function == TRANSMIT) return (rg.x.ax);
  1419.  
  1420.   return (0);
  1421. }
  1422.  
  1423.  
  1424.  
  1425. char pascal printm (char *text) {  /*  PRINTS TO MODEM AND SCREEN */
  1426.  
  1427.   char *mmore;
  1428.   char *p=NULL;
  1429.   char *pp;
  1430.  
  1431.   getxbbstime();
  1432.   p = text;
  1433.   if (!p || !*p) return (0);
  1434.  
  1435.   if (strchr(p,'\xc') || strstr(p,"\x1b[2J")) lines=0;
  1436.  
  1437.   if (baud) {
  1438.     pp = p;
  1439.     while (*pp) {
  1440.         if (*pp == '\n' || (*pp == '\r' && pp[1] != '\n')) {
  1441.            while (!fossil(TRANSMIT,'\r')) carrchk();
  1442.            *pp = '\n';
  1443.         }
  1444.         while (!fossil(TRANSMIT,*pp++)) carrchk();
  1445.      }
  1446.    }
  1447.  
  1448.    pp = p;
  1449.    while ((pp = strchr(pp,'\07')) != NULL) memmove(pp,&pp[1],strlen(pp));
  1450.    ansi(p);
  1451.    if (baud<4800 && text[1]) fossil(FLUSHOUT,0);
  1452.  
  1453.      if (!pauser) {
  1454.        lines=0;
  1455.        return (0);
  1456.      }
  1457.      if (pauser == 2) return(0);
  1458.  
  1459.      if (++lines >= (numlines - 1)) {
  1460.         pauser = 0;
  1461.         printm ("More? (Y-n) ");
  1462.         fossil(FLUSHOUT,0);
  1463.         fossil(PURGEIN,0);
  1464.         mmore = genin(1,0,1,1,YESNOM);
  1465.         printm ("\b\b\b\b\b\b\b\b\b\b\b\b           \b\b\b\b\b\b\b\b\b\b\b");
  1466.         if (*mmore == 'N') {
  1467.            printm ("\n");
  1468.            return (1);
  1469.         }
  1470.         pauser = 1;
  1471.     }
  1472.    return (0);
  1473. }
  1474.  
  1475.  
  1476.  
  1477. void cdecl deinitialize (void) {  /*  DEINITIALIZES FOSSIL ON EXIT */
  1478.  
  1479.  fossil(FLUSHOUT,0);
  1480.  fossil (DEINIT,0);
  1481.  fcloseall();
  1482.  ansi("\x1b[0m\x1b[2JLineEd down...\n");
  1483. }
  1484.  
  1485.  
  1486.  
  1487. char * pascal genin (length,password,caps,hot,type)  /* GENERIC INPUT ROUTINE */
  1488.  
  1489. char length;
  1490. char password;
  1491. char caps;
  1492. char hot;
  1493. char type;
  1494.  
  1495. {
  1496.  
  1497. static char input[257];
  1498. int x=0;
  1499. char one=0;
  1500. char temp;
  1501. char randchr[2];
  1502.  
  1503.  pauser=0;
  1504.  
  1505.  if (*temporary) {
  1506.     temporary[length]=0;
  1507.     strcpy(input,temporary);
  1508.     printm(input);
  1509.     x=strlen(input);
  1510.  }
  1511.  else {
  1512.     length--;
  1513.     strset(input,0);
  1514.  }
  1515.  
  1516.  startt=getxbbstime();
  1517.  
  1518. AfterChat:
  1519.  
  1520.  while ((getxbbstime()-startt)<241) {
  1521.  
  1522.   one=inkey();
  1523.   if (one == '\r') break;
  1524.  
  1525.   if (one=='\t') {
  1526.     one=0;
  1527.     for(;x<=length;++x) {
  1528.         if (++one>4) break;
  1529.         printm(" ");
  1530.         input[x]=' ';
  1531.         temporary[x]=' ';
  1532.         input[x+1]=0;
  1533.     }
  1534.     goto AfterCtrl;
  1535.   }
  1536.   if (one==25) {
  1537.     if (strlen(temporary)<=strlen(input)) continue;
  1538.     one=strlen(input);
  1539.     printm(&temporary[one]);
  1540.     strcat(input,&temporary[one]);
  1541.     x=strlen(input);
  1542.     goto AfterCtrl;
  1543.   }
  1544.   if (one==24) {
  1545.     if (strlen(temporary)<=strlen(input)) continue;
  1546.     one=strlen(input);
  1547.     input[x]=temporary[one];
  1548.     printm(&input[x++]);
  1549.     goto AfterCtrl;
  1550.   }
  1551.   if (one==26) {
  1552.     if (strlen(temporary)<strlen(input)) continue;
  1553.     while (input[x]==' '  && *input) {
  1554.                 input[x--]=0;
  1555.                 if (input[x]==' ' && *input) printm(BACKSPACE);
  1556.     }
  1557.     while (input[x]!=' ' && *input) {
  1558.                 input[x--]=0;
  1559.                 if (input[x]!=' ' && *input) printm(BACKSPACE);
  1560.     }
  1561.     while ((input[x]==' ') && (strlen(input)>0)) {
  1562.                 input[x--]=0;
  1563.                 if (*input) printm(BACKSPACE);
  1564.     }
  1565.     x=strlen(input);
  1566.     goto AfterCtrl;
  1567.   }
  1568.   if (one==23) {
  1569.     if (!strrchr(&temporary[strlen(input)],' ')) continue;
  1570.     one=strlen(input);
  1571.     while (temporary[one]==' ')  {
  1572.                 input[x++]=temporary[one];
  1573.                 if (temporary[one++]==' ') printm(" ");
  1574.     }
  1575.     while ((temporary[one]!=' ') && (temporary[one])) {
  1576.                 input[x++]=temporary[one];
  1577.                 if (temporary[one++]!=' ') printm(&input[x-1]);
  1578.     }
  1579.     x=strlen(input);
  1580.     goto AfterCtrl;
  1581.   }
  1582.   if (one==22) {
  1583.     if (strlen(temporary)<strlen(input)) continue;
  1584.     one=strlen(input);
  1585.     temp=strlen(&temporary[one]);
  1586.     memmove(&temporary[one+1],&temporary[one],temp+1);
  1587.     temporary[one]=' ';
  1588.     temporary[length]=0;
  1589.     goto AfterCtrl;
  1590.   }
  1591.   if (one==21) {
  1592.     if(!strlen(input) || strlen(temporary)<strlen(input)) continue;
  1593.     one=strlen(input);
  1594.     temp=strlen(&temporary[one]);
  1595.     memmove(&temporary[one-1],&temporary[one],temp+1);
  1596.     goto AfterCtrl;
  1597.   }
  1598.   if (one==20) {
  1599.     while (*input) {
  1600.         printm(BACKSPACE);
  1601.         input[strlen(input)-1]=0;
  1602.     }
  1603.     x=strlen(input);
  1604.     goto AfterCtrl;
  1605.   }
  1606.  
  1607.  
  1608. Nogo:
  1609.  
  1610.   if ((one == 8) || (one == 127)) {
  1611.       if (x>0) {
  1612.          printm(BACKSPACE);
  1613.          input [--x]=0;
  1614.          if ((type==PHONE) && ((x==2) || (x==5))) printm(BACKSPACE);
  1615.          if ((type==DATE) && ((x==1) || (x==3))) printm(BACKSPACE);
  1616.       }
  1617.       continue;
  1618.   }
  1619.   if ((caps) || (type==YESNO) || (type==YESNOM) || (type==FLE) || (type==FLEW) || (type==FLEPW) || (type==FLEP)) one=toupper(one);
  1620.   if (x <= length)
  1621.     {
  1622.       if (type==NAME)
  1623.        {
  1624.         if((isalpha(one)==0) && (one!=' ') && (one!='.') && (one!='-') || (x==0 && one==' ')) continue;
  1625.         if ((one==' ') && (strchr(input,' ')!=NULL)) continue;
  1626.        }
  1627.       if (type==NEAT)
  1628.        {
  1629.     if((isalnum(one)==0) && (one!=' ') || (x==0 && one==' ')) continue;
  1630.        }
  1631.       if ((type==NEAT) || (type==NAME))
  1632.        {
  1633.     if(x==0) one=toupper(one);
  1634.          else one=tolower(one);
  1635.        }
  1636.       if((type==NEAT) || (type==NAME))
  1637.        {
  1638.         if((x>0) && ((input[x-1]==' ') || (input[x-1]=='.') || (input[x-1]=='-'))) one=toupper(one);
  1639.        }
  1640.       if ((type==SUBJECT) && (x==0)) one=toupper(one);
  1641.       if ((type==SUBJECT) && (isprint(one)==0)) continue;
  1642.       if ((type==ALLL) && (isprint(one)==0) && (mode==1)) continue;
  1643.       if ((type==ALLL) && (one==127)) one=8;
  1644.       if ((type==ALPHA) && (isalpha(one)==0) && (one!=' ')) continue;
  1645.       if (((type==NUM) || (type==PHONE) || (type==DATE)) && (isdigit(one)==0)) continue;
  1646.       if ((type==ALPHANUM) && (isalnum(one)==0) && (one!=' ')) continue;
  1647.       if (((type==YESNO) || (type==YESNOM)) && (one!='Y' && one!='N')) continue;
  1648.       if (type==FLE)
  1649.     {
  1650.      if ((isalnum(one)==0) && (!strchr("._-+=!@#$%^&<>/",one))) continue;
  1651.     }
  1652.       if (type==FLEP)
  1653.         {
  1654.          if ((isalnum(one)==0) && (!strchr("._-+=!@#$%^&<>/\\:",one))) continue;
  1655.     }
  1656.       if (type==FLEW)
  1657.     {
  1658.           if ((isalnum(one)==0) && (!strchr("._-+=!@#$%^&<>/?*",one))) continue;
  1659.     }
  1660.       if (type==FLEPW)
  1661.     {
  1662.        if ((isalnum(one)==0) && (!strchr("._-+=!@#$%^&<>/?*\\:",one))) continue;
  1663.     }
  1664.       if ((type==FLE) || (type==FLEP) || (type==FLEW) || (type==FLEPW))
  1665.     {
  1666.      if ((one=='.') && (strchr(input,'.')!=NULL)) continue;
  1667.     }
  1668.      }
  1669.  
  1670.   if ((one==1) && (strncmp(fname,"MSGTMP",6)==0)) continue;
  1671.   if (strchr("\x3\x11\x13\x0b",one)) continue;
  1672.   if (one && x <= length) {
  1673.       input[x]=one;
  1674.       temporary[x]=one;
  1675.       input[++x]=0;
  1676.       if (type==YESNOM) {
  1677.                         strset(temporary,0);
  1678.                         return(input);
  1679.       }
  1680.       if (!password) printm(&input[x-1]);
  1681.       else {
  1682.         randchr[0]=random(10)+33;
  1683.         randchr[1]=0;
  1684.         printm(randchr);
  1685.       }
  1686.       if ((type==PHONE) && ((x==3) || (x==6))) printm("-");
  1687.       if ((type==DATE) && ((x==2) || (x==4))) printm("/");
  1688. AfterCtrl:
  1689.       if ((hot)&&(x >= length)) {
  1690.             strset(temporary,0);
  1691.             return (input);
  1692.       }
  1693.       startt=getxbbstime();
  1694.     }
  1695.  
  1696.   }
  1697.  
  1698.   if (((getxbbstime()-startt)>240) && (!chatted))
  1699.     {
  1700.       aprintf("\nUser time-out...\n");
  1701.       exit (2);
  1702.     }
  1703.  
  1704.   if (chatted) {
  1705.         chatted=0;
  1706.         strset(input,0);
  1707.         strset(temporary,0);
  1708.         return (input);
  1709.   }
  1710.  
  1711.   strset(temporary,0);
  1712.   return (input);
  1713.  
  1714. }
  1715.  
  1716.  
  1717. char pascal carrchk (void) { /* Checks for carrier */
  1718.  
  1719.   rg.x.dx=commport;
  1720.   rg.h.ah=GETSTAT;
  1721.   int86(20,&rg,&rg);
  1722.   if(baud) {
  1723.      if (!(rg.h.al & 128)) {
  1724.        rg.x.dx=commport;
  1725.        rg.h.ah=GETSTAT;
  1726.        int86(20,&rg,&rg);
  1727.        if (!(rg.h.al & 128)) {
  1728.          fossil(DTR,DOWN);
  1729.          ansi("\n\x1b[KLost carrier...");
  1730.          if (!strncmp(fname,"MSGTMP",6)) {
  1731.             remove(fname);
  1732.             if(fname[strlen(fname)-1]!='.') strcat(fname,".");
  1733.             strcat(fname,"HDR");
  1734.             remove(fname);
  1735.          }
  1736.          exit (2);
  1737.        }
  1738.      }
  1739.   }
  1740.   return (rg.h.ah);
  1741. }
  1742.  
  1743.  
  1744.  
  1745. void pascal chat (void) {
  1746.  
  1747.  char a[81];
  1748.  char wrapped[81];
  1749.  int register x;
  1750.  char tempflag;
  1751.  
  1752.  strset(temporary,0);
  1753.  
  1754.  if (chatted) return;
  1755.  printm("\n\nChat mode engaged\n\n");
  1756.  
  1757.  while (chatting) {
  1758.      strcpy(a,genin((uwidth-1),0,0,1,ALLL));
  1759.      strcat(temporary,a);
  1760.      strcpy(a,temporary);
  1761.      strset(temporary,0);
  1762.      if (!chatting) break;
  1763.      if (strlen(a)>=(uwidth-2)) {
  1764.         if (a[strlen(a)-1]!=' ' && strchr(a,' ')) {
  1765.             strset(wrapped,0);
  1766.             x=strlen(a)-1;
  1767.             for (;strlen(a)>0;x--) {
  1768.                 if (a[x]!=' ') {
  1769.                     printm(BACKSPACE);
  1770.                     strcat(wrapped,&a[x]);
  1771.                     a[x]=0;
  1772.                 }
  1773.                 else break;
  1774.             }
  1775.             strcpy(temporary,strrev(wrapped));
  1776.             printm("\n");
  1777.         }
  1778.         else printm("\n");
  1779.      }
  1780.      else printm("\n\n");
  1781.  }
  1782.  printm("\nChat mode ended\n");
  1783.  chatted++;
  1784.  strset(temporary,0);
  1785.  status(1);
  1786.  status(2);
  1787. }
  1788.  
  1789.  
  1790. long pascal getxbbstime (void) {
  1791.  
  1792.  char tempause;
  1793.  static long xbbs_time;
  1794.  static long last_time=0L;
  1795.  static int warned;
  1796.  
  1797.   tempause=pauser;
  1798.   pauser=2;
  1799.   xbbs_time=time(NULL);
  1800.  
  1801.   if (timelimit<(xbbs_time+120L) && !warned) {
  1802.  
  1803.     int x;
  1804.  
  1805.     warned++;
  1806.     x=wherex();
  1807.     printfm("\nWARNING: %u minutes remaining for this call.\n",(timelimit-xbbs_time)/60L);
  1808.     status(1);
  1809.     status(2);
  1810.     while(--x) printm(" ");
  1811.   }
  1812.  
  1813.   if (timelimit > ((xbbs_time+1L)+120L) && warned) warned=0;
  1814.  
  1815.   if (timelimit < (xbbs_time+1L)) {
  1816.     timelimit=xbbs_time+240L;
  1817.     printm ("\nSorry, time to logoff...\n");
  1818.     fossil (FLUSHOUT,0);
  1819.     exit(0);
  1820.   }
  1821.  
  1822.   if((xbbs_time-last_time)>60L) {
  1823.     last_time=xbbs_time;
  1824.     status(1);
  1825.     status(2);
  1826.   }
  1827.   pauser=tempause;
  1828.   return(xbbs_time);
  1829. }
  1830.  
  1831.  
  1832.  
  1833.  
  1834. void pascal rawdir (char *directory,char type) {
  1835.  
  1836.  int register x=0;
  1837.  char b;
  1838.  char *noe;
  1839.  char noext[10];
  1840.  char a[124];
  1841.  char mask[81];
  1842.  struct ffblk f;
  1843.  struct fdate
  1844.   {
  1845.    bit day:   5;
  1846.    bit month: 4;
  1847.    bit year:  7;
  1848.   };
  1849.  union df
  1850.   {
  1851.    struct fdate fd;
  1852.    int x;
  1853.   } fdf;
  1854.  ulong total=0;
  1855.  
  1856.   if ((type) && (type!=1)) {
  1857.     sprintf(a,"%s",directory);
  1858.     goto Skipask;
  1859.   }
  1860.  
  1861.   printm("\nMask? [*.*]: ");
  1862.   if (!type) strcpy(mask,genin(12,0,1,0,FLEW));
  1863.   else strcpy(mask,genin(80,0,1,0,FLEPW));
  1864.  
  1865.   if (!*mask)
  1866.    {
  1867.     strcpy(mask,"*.*");
  1868.     printm("*.*");
  1869.    }
  1870.  
  1871.   printm("\n");
  1872.  
  1873.   sprintf(a,"%s%s",directory,mask);
  1874.  
  1875. Skipask:
  1876.  
  1877.   if (findfirst(a,&f,0))
  1878.    {
  1879.     printm("\nNo matching files found.\n");
  1880.     return;
  1881.    }
  1882.  
  1883.   printm("\n[Space] to halt\n");
  1884.   pauser=1;
  1885.  
  1886.   do
  1887.    {
  1888.     x++;
  1889.     if ((!type) || (type==1))
  1890.      {
  1891.       if (!(x%2)) b='\n';
  1892.       else b=' ';
  1893.      }
  1894.      else
  1895.       {
  1896.        if (!(x%3)) b='\n';
  1897.        else b=' ';
  1898.       }
  1899.  
  1900.      strcpy(noext,f.ff_name);
  1901.      noe=strchr(noext,'.');
  1902.      if (noe) noe[0]=0;
  1903.      total=total+f.ff_fsize;
  1904.      fdf.x=f.ff_fdate;
  1905.  
  1906.      if (graphics)
  1907.       {
  1908.        if (type==2) sprintf(mask,"\x1b[0;1;33m%-9s  \x1b[34m%02u/%02u/%u  %c",noext,fdf.fd.month,fdf.fd.day,(fdf.fd.year+80)%100,b);
  1909.        else sprintf(mask,"\x1b[0;1;33m%-13s  \x1b[36m%6lu  \x1b[34m%02u/%02u/%u       %c",f.ff_name,f.ff_fsize,fdf.fd.month,fdf.fd.day,(fdf.fd.year+80)%100,b);
  1910.       }
  1911.      else
  1912.       {
  1913.        if (type==2) sprintf(mask,"%-9s  %02u/%02u/%u  %c",noext,fdf.fd.month,fdf.fd.day,(fdf.fd.year+80)%100,b);
  1914.        else sprintf(mask,"%-13s  %6lu  %02u/%02u/%u       %c",f.ff_name,f.ff_fsize,fdf.fd.month,fdf.fd.day,(fdf.fd.year+80)%100,b);
  1915.       }
  1916.  
  1917.     if (b==' ') lines--;
  1918.     if(printm(mask)) break;
  1919.     b=toupper(inkey());
  1920.     if (b==' ') break;
  1921.  
  1922.    }
  1923.   while(!findnext(&f));
  1924.  
  1925.  
  1926. donereading:
  1927.  
  1928.   pauser=0;
  1929.   noext[0]=0;
  1930.   if (graphics) strcpy(noext,"\x1b[0;1;32m");
  1931.   printfm("\n%s%u matching files found totalling %lu bytes.",noext,x,total);
  1932.   if (graphics) printm("\x1b[0;1;31m");
  1933.   hitreturn();
  1934.   status(1);
  1935.   status(2);
  1936.   ansi("\n");
  1937. }
  1938.  
  1939.  
  1940. void pascal hitreturn (void) {
  1941.  
  1942.            startt=getxbbstime();
  1943.            lines=0;
  1944.            printm("\n[Enter] to continue...");
  1945.            while ((getxbbstime()-startt)<241L) {
  1946.              if ((inkey()==13) || (chatted)) goto hedid;
  1947.            }
  1948.            aprintf("\n\x1b[KUser time-out...");
  1949.            exit (2);
  1950. hedid:
  1951.            chatted=0;
  1952.            printm("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b                      \n");
  1953.            lines=0;
  1954.  
  1955. }
  1956.  
  1957.  
  1958.  
  1959. char * pascal rstrip (char *a) {
  1960.  
  1961.   int register x;
  1962.  
  1963.   x=strlen(a);
  1964.   while (x && a[x-1]==' ') a[--x]=0;
  1965.   return a;
  1966. }
  1967.  
  1968.  
  1969. int pascal checkafile (char *a) {
  1970.  
  1971.  return (findfirst(a,&filestat,0));
  1972. }
  1973.  
  1974.  
  1975. void pascal printheader () {
  1976.  
  1977.   char header[]="\n    [----+----1----+----2----+----3----+----4----+----5----+----6----+----7--";
  1978.  
  1979.   printg("\x1b[0;1;37m");
  1980.   header[uwidth-1]=0;
  1981.   printfm("%s]",header);
  1982.   printg("\x1b[0;1;32m");
  1983. }
  1984.  
  1985.  
  1986. void pascal quoter () {
  1987.  
  1988.       if (checkafile(fname)) {
  1989.         printm("\nNo quotes available\n");
  1990.         return;
  1991.       }
  1992.       quoting=1;
  1993.       load(1);
  1994.       quoting=0;
  1995. }
  1996.  
  1997.  
  1998.  
  1999. void pascal movelines() {
  2000.  
  2001.   char s[81];
  2002.   word linenum,x,z;
  2003.   struct line *blkbeg,*blkend,*leftend,*rightend,*movbeg,*movend,*info;
  2004.  
  2005.  
  2006.                   linenum=findlast();
  2007.                   if (linenum<2) return;
  2008.                   printg("\x1b[0;1;37m");
  2009.                   printfm("Move line (1-%u) #",linenum);
  2010.                   strcpy(s,genin(5,0,0,0,NUM));
  2011.                   if (!*s) {
  2012.                      printm("\nAborted\n");
  2013.                      return;
  2014.                   }
  2015.                   else {
  2016.                     linenum=atoi(s);
  2017.                     if (linenum==findlast()) {
  2018.                             x=linenum;
  2019.                             goto SkipNext;
  2020.                     }
  2021.                     if ((linenum<1) || (linenum>findlast())) {
  2022.                        printm("\nAborted");
  2023.                        return;
  2024.                     }
  2025.                     printm("-#");
  2026.                     strcpy(s,genin(5,0,0,0,NUM));
  2027.                     if (!*s) {
  2028.                         x=linenum;
  2029.                         printfm("%u",x);
  2030.                     }
  2031.                     else {
  2032.                         x=atoi(s);
  2033.                         if ((x<linenum) || (x>findlast())) {
  2034.                                                         printm("\nAborted");
  2035.                                                         return;
  2036.                         }
  2037.                     }
  2038. SkipNext:
  2039.                     printm(" to which #");
  2040.                     strcpy(s,genin(5,0,0,0,NUM));
  2041.                     z=atoi(s);
  2042.                     if ((z<1) || (z>findlast()) || ((z>=linenum)&&(z<=x))) {
  2043.                         printm("\nAborted");
  2044.                         return;
  2045.                     }
  2046.                     if (z<linenum) {
  2047.                             leftend=find(z-1);
  2048.                             movbeg=find(z);
  2049.                             movend=find(linenum-1);
  2050.                             blkbeg=find(linenum);
  2051.                             blkend=find(x);
  2052.                             rightend=find(x+1);
  2053.                     }
  2054.                     else {
  2055.                             leftend=find(linenum-1);
  2056.                             movbeg=find(linenum);
  2057.                             movend=find(x);
  2058.                             blkbeg=find(x+1);
  2059.                             blkend=find(z);
  2060.                             rightend=find(z+1);
  2061.                     }
  2062.                     if (!leftend) {
  2063.                             blkbeg->prior=NULL;
  2064.                             start=blkbeg;
  2065.                     }
  2066.                     else {
  2067.                             leftend->next=blkbeg;
  2068.                             blkbeg->prior=leftend;
  2069.                          }
  2070.                     if (!rightend) {
  2071.                             movend->next=NULL;
  2072.                             last=movend;
  2073.                     }
  2074.                     else {
  2075.                         rightend->prior=movend;
  2076.                         movend->next=rightend;
  2077.                     }
  2078.                     blkend->next=movbeg;
  2079.                     movbeg->prior=blkend;
  2080.  
  2081.                     x=1;
  2082.                     info=start;
  2083.                     while(info) {
  2084.                         info->num=x++;
  2085.                         info=info->next;
  2086.                     }
  2087.                   }
  2088.                   printm("\nMove complete\n");
  2089. }
  2090.  
  2091.  
  2092. void pascal status (char type) {
  2093.  
  2094.   int x,y,oldx,oldy;
  2095.  
  2096.   get_hardcursorpos(&oldx,&oldy);
  2097.   if (!type) {
  2098.     for(x = 0;x < fakemaxx;x++) {
  2099.       put_char(' ',112,(fakemaxx - 1) - x,maxy - 1);
  2100.     }
  2101.   }
  2102.   else if (type == 1) {
  2103.         x = dprintf(0,maxy - 1,112," %s @ %u Baud %c %s %c",username,baud,177,fname,177);
  2104.         if (chatting) x += dprintf(fakemaxx - x,maxy - 1,112," <C>");
  2105.         for (y = 0;y < fakemaxx - x;y++) put_char(' ',112,(fakemaxx - 1) - y,maxy - 1);
  2106.   }
  2107.   else {
  2108.         dprintf(fakemaxx - 9,maxy - 1,112,"%03ld mins",(timelimit - getxbbstime()) / 60L);
  2109.   }
  2110.   pos_hardcursor(oldx,oldy);
  2111. }
  2112.  
  2113.  
  2114.  
  2115. void pascal quit (char type) {
  2116.  
  2117.  if (!type) {
  2118.      printm("Quit (abort)...are you sure? (Y-n) ");
  2119.      if (*genin(1,0,1,1,YESNO)=='N') {
  2120.          printm("\n");
  2121.          return;
  2122.      }
  2123.  }
  2124.  
  2125.  if ((mode) && (!type)) {
  2126.      if (!strncmp(fname,"MSGTMP",6)) {
  2127.         remove(fname);
  2128.         if(fname[strlen(fname)-1]!='.') strcat(fname,".");
  2129.         strcat(fname,"HDR");
  2130.         remove(fname);
  2131.      }
  2132.      exit(1);
  2133.  }
  2134.  else exit(0);
  2135. }
  2136.  
  2137.  
  2138. int pascal printg (char *text) {
  2139.  
  2140.   if(graphics) return printm(text);
  2141.   return 0;
  2142. }
  2143.